﻿namespace NetFx.SMIL.Definitions
{
  using System;
  using System.Text;
  using System.Collections;

  using System.Reflection;
  using System.Reflection.Emit;
  using System.Runtime.InteropServices;

  using System.Diagnostics;
  using System.Diagnostics.CodeAnalysis;
  using System.Diagnostics.SymbolStore;
  using System.Security;
  using System.Security.Permissions;

  using NetFx.MSIL;
  using NetFx.MSIL.Headers;

  public class TypeDefinition : ComplexDefinition
  {
    #region Statics
    public static TypeDefinition of(string name)
    {
      return new TypeDefinition(name);
    }
    #endregion
    #region Fields
    protected string parent;
    protected ArrayList interfaceDefs = new ArrayList();
    #endregion
    #region Properties
    public virtual TypeHeader InstanceHeader
    {
      get
      {
        return this.header as TypeHeader;
      }
    }
    public virtual string Parent
    {
      get
      {
        return this.parent;
      }
      set
      {
        this.parent = value;
      }
    }
    public virtual IList InterfaceDefinitions
    {
      get
      {
        return this.interfaceDefs;
      }
    }
    public virtual TypeAttributes Attributes
    {
      get
      {
        return this.InstanceHeader.Attributes;
      }
      set
      {
        this.InstanceHeader.Attributes = value;
      }
    }
    public virtual PackingSize PackingSize
    {
      get
      {
        return this.InstanceHeader.PackingSize;
      }
      set
      {
        this.InstanceHeader.PackingSize = value;
      }
    }
    #endregion
    #region Constructors
    public TypeDefinition(string name)
      : this(TypeHeader.of(name))
    {

    }
    public TypeDefinition(TypeHeader header)
      : base(header)
    {

    }
    #endregion
    #region Methods
    public virtual TypeDefinition AddInterface(string name)
    {
      TypeDefinition interfaceType = ComplexDefinition.CreateTypeDefinition(name) as TypeDefinition;
      if (interfaceType != null)
      {
        this.InterfaceDefinitions.Add(interfaceType);
      }
      return interfaceType;
    }
    public virtual TypeDefinition RemoveInterface(string name)
    {
      TypeDefinition interfaceType = this.GetInterface(name);
      if (interfaceType != null)
      {
        this.InterfaceDefinitions.Remove(interfaceType);
      }
      return interfaceType;
    }
    public virtual TypeDefinition GetInterface(string name)
    {
      foreach (TypeDefinition interfaceType in this.InterfaceDefinitions)
      {
        if (interfaceType.Name == name)
          return interfaceType;
      }
      return null;
    }

    public virtual TypeDefinition DefineType(string name)
    {
      return this.AddDefinition(
        ComplexDefinition.CreateTypeDefinition(name)
        ) as TypeDefinition;
    }
    public virtual EnumDefinition DefineEnum(string name)
    {
      return this.AddDefinition(
        ComplexDefinition.CreateEnumDefinition(name)
        ) as EnumDefinition;
    }
    public virtual MethodDefinition DefineMethod(string name)
    {
      return this.AddDefinition(ComplexDefinition.CreateMethodDefinition(name))
        as MethodDefinition;
    }

    public virtual FieldDefinition DefineField(string name)
    {
      return this.AddDefinition(ComplexDefinition.CreateFieldDefinition(name))
        as FieldDefinition;
    }

    public virtual FieldDefinition DefineEvent(string name)
    {
      return this.AddDefinition(ComplexDefinition.CreateEventDefinition(name))
        as FieldDefinition;
    }

    public virtual FieldDefinition DefineProperty(string name)
    {
      return this.AddDefinition(ComplexDefinition.CreatePropertyDefinition(name))
        as FieldDefinition;
    }

    protected override void Resolve(ComplexDefinition container)
    {

    }
    #endregion
  }

}